#include <string>
#include "Scene.h"
#include "MeshModel.h"
#include "Grid.h"
#include "SmartPtr.h"

using std::string;

Scene::Scene()
{
	CvarSystem& cvars = CvarSystem::getInstance();

	_activeModel = cvars.addCvar("s_active_model", -1);
	_activeCamera = cvars.addCvar("s_active_camera", 0);	
	_wireframeColor = cvars.getCvar("r_wireframe_color", true);
	_wireframeColorSelected = cvars.addCvar("s_wireframe_color_selected", YELLOW);

	// add default camera
	addCamera(CameraPtr(new Camera()));
	
	// add grid+axis model
	addModel(ModelPtr(new Grid(1.0f, 0.1f)));
}

void Scene::addModel(ModelPtr model)
{
	_models.push_back(model);
}

void Scene::addCamera(CameraPtr camera)
{
	_cameras.push_back(camera);
}

void Scene::render(RendererPtr renderer)
{
	CameraPtr camera = getActiveCamera();
	if (camera.hasValue()) {
		renderer->setCamera(camera);

		for (unsigned int i = 0; i < _models.size(); ++i) {
			if (i == _activeModel->getValueI() + 1) {
				int color = _wireframeColor->getValueI();
				_wireframeColor->setValue(_wireframeColorSelected->getValueI());
				_models[i]->render(renderer);
				_wireframeColor->setValue(color);
			}
			else {
				_models[i]->render(renderer);
			}			
		}
	}

	for (unsigned int i = 0; i < _cameras.size(); ++i) {
		if (i != _activeCamera->getValueI()) {
			_cameras[i]->drawMark(renderer);
		}
	}
}

CameraPtr Scene::getActiveCamera()
{
	int activeCamera = _activeCamera->getValueI();
	if (activeCamera >= 0 && activeCamera < (int) _cameras.size())
		return _cameras[activeCamera];

	return CameraPtr(NULL);
}

ModelPtr Scene::getActiveModel()
{
	unsigned int model = _activeModel->getValueI() + 1; // +1 to ignore the grid model

	if (model >= 0 && model < _models.size()) {
		return _models[model];
	}

	return ModelPtr(NULL);
}